package com.example.leonard.controller;

import com.alibaba.fastjson.JSON;
import com.example.leonard.annotation.RateLimit;
import com.example.leonard.common.enums.RedisKeyEnum;
import com.example.leonard.core.domain.Customer;
import com.example.leonard.core.domain.Employee;
import com.example.leonard.core.thread.MyCallableThread;
import com.example.leonard.core.thread.MyRunnableTask;
import com.example.leonard.service.ICustomerService;
import com.example.leonard.service.IEmployeeService;
import com.example.leonard.service.impl.EmployeeServiceImpl;
import com.example.leonard.wapper.ResultWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.concurrent.*;

import static com.example.leonard.common.enums.RedisKeyEnum.RATE_LIMIT;

@RestController
@RequestMapping("/api")
@Api(value = "swagger测试")
public class FrontController {
    @Autowired
    private IEmployeeService employeeService;
    @Autowired
    private ICustomerService customerService;
    private ThreadPoolExecutor threadPoolExecutor =
            new ThreadPoolExecutor(5, 10, 60, TimeUnit.MICROSECONDS, new LinkedBlockingDeque<>(200));
    private static final Logger LOGGER = LoggerFactory.getLogger(EmployeeServiceImpl.class);

    /**
     * @param id
     * @return
     */
    @RequestMapping(value = "/front", method = RequestMethod.GET)
    @ApiOperation(value = "用户查询", notes = "查询用户的信息")
//    @RateLimit(value = RATE_LIMIT)
    public ResultWrapper<Employee> front(@RequestParam(value = "id") Long id, HttpServletRequest request) {
        Employee employee = employeeService.selectById(id);
        return ResultWrapper.success(employee);
    }

    /**
     * @param id
     * @return
     */
    @RequestMapping(value = "/cus", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "客户查询", notes = "查询客户的信息")
    public Customer seletcCustomer(@RequestParam(value = "id") Long id) {
        Customer customer = customerService.selectCustomerById(id);
        return customer;
    }

    /**
     * 自定义线程池与blocking绑定
     */
    @RequestMapping(value = "/thread", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "自定义线程池", notes = "自定义线程池的测试")
    public void printThreadPool() {
        LOGGER.info("===================线程开始===========================");
        MyRunnableTask myRunnableTask = new MyRunnableTask();
        threadPoolExecutor.submit(myRunnableTask);
    }

    @RequestMapping(value = "threads", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "线程池匿名内部类", notes = "匿名内部类测试")
    public void newThreadPool() {
        for (int i = 0; i < 5; i++) {
            Employee employee = new Employee();
            employee.setAge(10 + i);
            employee.setUsername("对象" + i);
            threadPoolExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    LOGGER.info("当前打印的对象->{}", JSON.toJSONString(employee));
                }
            });
        }
        System.out.println("主线程呀");
    }

    @RequestMapping(value = "/lambda", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "lambda表达式", notes = "lambda表达式的测试")
    public void newPrintThreadPool() {
        for (int i = 0; i < 5; i++) {
            Employee employee = new Employee();
            employee.setAge(10 + i);
            employee.setUsername("对象" + i);
            threadPoolExecutor.execute(() -> {
                LOGGER.info("当前打印的对象->{}", JSON.toJSONString(employee));
            });
        }
        System.out.println("主线程啊");
    }

    @RequestMapping(value = "/callable", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "线程池返回值", notes = "有返回值的线程池的测试")
    public void callable() {
        LOGGER.info("==============开始===================");
        HashMap<String, Object> map = new HashMap<>();
        for (int i = 0; i < 5; i++) {
            Employee employee = new Employee();
            employee.setAge(10 + i);
            employee.setUsername("对象" + i);
            MyCallableThread myCallableThread = new MyCallableThread(employee);
            Future submit = threadPoolExecutor.submit(myCallableThread);
            try {
                boolean bool = (boolean) submit.get();
                map.put("" + i, bool);
                LOGGER.info("当前的对象为->{},返回的结果为->{}:", JSON.toJSONString(employee), bool);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        LOGGER.info("当前的对象返回的结果为->{}:", JSON.toJSONString(map));
        System.out.println("主线程呀");
    }
}

